Yalmip + Gurobi使用进阶(二) 您所在的位置:网站首页 yalmip implies Yalmip + Gurobi使用进阶(二)

Yalmip + Gurobi使用进阶(二)

2023-04-05 01:13| 来源: 网络整理| 查看: 265

建模仿真的时候,最怕的就是:辛辛苦苦花了好几天把模型编写出来,认真检查,连文章里的每一个字母是向量还是标量都仔仔细细检查了几遍,然后满怀期待的开始运行,然后——infeasible——BOOM!!!——救命啊!!!我曾经有段时间连续复现过三篇文章,每篇都因为各种原因infeasible,当时真的是怀疑人生,想换课题。不过后来还是通过一些方法解决了,殊为不易。

本文不涉及数学原理,只是讲一下Gurobi求解器的使用技巧和常见问题。

1 检查模型

第一点,也是很重要的一点,再仔细检查一遍模型。主要从两个方面下手——

1)首先看模型本身对不对,有些自己提的模型可能本身存在错误——比如双层变单层、去绝对值的变换错了——而没有可行解。这时候可以试着简化一下模型,缩减变量规模,改一些参数,人工寻找有没有可行解,如果自己确定肯定有可行解,但是计算结果还是infeasible,那就是其它方面出了问题了。

2)其次看有没有程序编写错误。如果是别人写的文章,更要注意这一点。开头说了字母的向量/标量问题,还有正负号之类的,有一个仿真我检查了半天,改了几处错误之后还是不行,怀疑是模型就是错误的,最后偶然发现一个 \le 写成了 \geq ,真的是万万没想到,这都能错,改正之后,模型就可以运行了,而且是得到了和原文一样的结果!所以说还是要认真检查啊!

向量和标量交错的符号2 检查模型是否非线性、非凸

我和同学讨论非线性问题用什么求解器解的时候,他一脸茫然:“Gurobi能算非线性问题?”直接建议我用别的专门的非线性求解器。

那让我们来看一下Gurobi究竟能求解哪些问题。Gurobi中国官网(GUROBI-Gurobi 中国)的产品介绍里写到(截至2021.5.10)

Gurobi 是全局优化器,支持的模型类型包括:(1)连续和混合整数线性问题(2)凸目标或约束连续和混合整数二次问题(3)非凸目标或约束连续和混合整数二次问题(4)含有对数、指数、三角函数、高阶多项式目标或约束,以及任何形式的分段约束的非线性问题(5)含有绝对值、最大值、最小值、逻辑与或非目标或约束的非线性问题

个人觉得Gurobi强项是混整规划问题MIP,以及在大规模问题上的求解效率。Gurobi自9.0版本开始才支持非凸二次优化。如果待求解问题Gurobi不支持的话,那自然要换别的求解器了。

如果模型的目标函数约束中出现了二次项,求解不了或结果不行,那么可以尝试将参数NonConvex设为2。默认设置下,Gurobi是解不了二次非凸模型的,坑的地方在于,求解器不会告诉你需要手动设置一下才能求解。

目标函数和约束都带有二次项的程序,未设置NonConvex参数,以前运行会提示“…Q矩阵是非凸的…”(…Q maxtrix is nonconvex…),现在运行不报错了,但是也求不出结果

NonConvex参数就是Gurobi提供的处理非凸二次问题的参数。将这个参数设为2,Gurobi就会把非凸二次问题“双线性化”,然后应用spatial branching(spatial branch and bound,空间分支定界,就是分支定界法?)方法求解。

官方文档截图

这个参数在Yalmip中的设置方法可以参考我的另一篇文章[ClassmateMing:Yalmip + Gurobi使用进阶(一)——求解器参数设置]

3 使用Gurobi自带的函数Debug

这一部分主要参考了这篇文章 [王源:【Gurobi】针对优化模型Infeasible的错误,如何快速Debug?] ,原博主是用Gurobi的原生Python接口的,大家有兴趣也可以看看。主要介绍两个函数,但其实实际应用起来个人感觉意义不大。

3.1 计算不可约不一致子系统 gurobi_iis()

这个函数,在Gurobi的C、Python、Java接口里全部都是computeIIS(),到了Matlab、R语言里变成了gurobi_iis(),不知道为什么要这么整,当时找了好久才发现。

官方文档里就几句介绍,作用翻译过来就是,

IIS是约束的子集,具有以下属性: - 以IIS为代表的子系统是不可行的 - 如果IIS中任意约束被移除,子系统就会有可行解

云里雾里。参考的那篇博文里说意思是“可得到哪些约束是互相矛盾的,即去掉这些矛盾约束剩下的约束构成的问题是可行的。”实践当中发现基本确实是这样。具体用法为

iis = gurobi_iis(model);

model是规划问题模型,注意该模型需要是Gurobi支持的模型,实际使用时需要利用Yalmip或者别的途径把模型规范化。返回的iis是结构体struct,最少有minimal、Arows、lb、ub四个子元素。

下面演示一下函数用法:

% 测试computeIIS()、yalmip模型输出函数的脚本 clear;clc;close all; %% 变量声明 x = sdpvar(2, 1); %% 目标函数 y = x1 + 2 * x2 f = x(1) + 2 * x(2); %% 约束 % 显然第一行、第三行冲突 C = [ x(1) + x(2) >= 1.2, x(1)

可以看到iis.Arows中第一个和第三个标志位都为1,即出现冲突的约束位置。但是我在实际的很复杂的模型中用这个函数,会出现很多很多个1,参考意义不大。官方文档上说lb、ub元素意为:指示计算的IIS中是否出现下/上界的逻辑向量。也看不懂是什么意思,而且为什么三个约束,lb、ub只是2×1维向量,真怪。希望有大佬来指导一下。

3.2 利用gurobi_write()输出冲突的约束

gurobi_write()方法本来是gurobi提供的输出模型文件的函数,可以生成mps、rew、lp等通用格式的规划模型文件。

gurobi_write(model, 'TestModel.ilp'); % 用法:gurobi_write(Gurobi支持的模型,'文件名.ilp')

但是把文件后缀换成ilp,看结果该方法作用似乎变成了输出相冲突的约束,如果能用的话真的会很方便。但是很遗憾,这个方法/函数不能直接应用在Yalmip输出的模型上,哪位大佬会的话也可以私信、留言指导一下。

直接在3.1的程序下面运行这段代码,就会提示这个。佛了,同样都是Yalmip生成的model,gurobi自带的求解方法能解,gurobi_iis()方法也能运行,运行这句就说什么“没有IIS可用于当前模型”,真滴无语。

IIS原理还请参考[王源:【Gurobi】针对优化模型Infeasible的错误,如何快速Debug?],我没看懂

拓展阅读

非线性规划求解器 Lingo, Matlab 使用心得,及使用的求解算法

如果文章对你有帮助的话,请点个赞,谢谢 !



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有